#pragma once
#include "FoGGEDEF.h"
#include "foDataObject.h"
#include "aDataPartBase.h"


namespace _FOGGE_
{
	namespace _GDB_ 
	{
		FoImplementRTTI(aDataPartBase,foBaseObject);

		std::map<::_FO_UTIL::Name,::_FOGGE_::foUInt> g_mapNameCounterMap;

		TCHAR tempBuff[1024];


		aDataPartBase::aDataPartBase(int id)
		{
			m_nPartID=id;
			m_ptrDataObject=0;
			m_bIsDummy=false;

			m_uiDataModificationFlag=0;
			
		}

		void aDataPartBase::InitializeInternal()
		{
			std::map<::_FO_UTIL::Name,::_FOGGE_::foUInt>::iterator iter,end;

			iter=g_mapNameCounterMap.find(GetFoRTTI()->GetName());
			end=g_mapNameCounterMap.end();

			foUInt counter;

			if(iter==end)
			{//new one
				counter=0;
			}
			else
			{
				counter=iter->second;
			}

			foString newName(GetFoRTTI()->GetName().c_str());
			
			newName+=_itot(counter,tempBuff,10);

			//set uniqName
			m_nameUniqName=newName;

			//increase name counter
			g_mapNameCounterMap[GetFoRTTI()->GetName()]=counter+1;
		}

		aDataPartBase* aDataPartBase::Clone()
		{
				
			aDataPartBase* ptrCloned=m_ptrCloneFactory->CreatePart();

			//make a uniq name
			ptrCloned->InitializeInternal();


			ptrCloned->CopyFrom(this);


			return ptrCloned;
		}

		/*virtual*/
		void aDataPartBase::CopyFrom(aDataPartBase* ptrSource)
		{
			m_ptrCloneFactory=ptrSource->m_ptrCloneFactory;
			m_bIsDummy=ptrSource->m_bIsDummy;
		}

		/*virtual*/
		void aDataPartBase::IncRefCount()
		{
			m_ptrDataObject->IncRefCount();
		}
		/*virtual*/
		void aDataPartBase::DecRefCount()
		{
			m_ptrDataObject->DecRefCount();
		}



		/**
		base property
		*/
		//@{
		void aDataPartBase::NotifyBecomeNewMaster(aDataPartBase* ptrOldMaster)
		{
			m_vLocation=ptrOldMaster->m_vLocation;
			m_rRotation=ptrOldMaster->m_rRotation;
		}
		void aDataPartBase::SetToNewMaster()
		{
			NotifyBecomeNewMaster(m_ptrDataObject->GetMasterDataPart());
			m_ptrDataObject->SetMasterDataPart(this);
		}

		const _FOMATH::Vector& aDataPartBase::GetLocation()
		{
			assert(m_ptrDataObject&&"aDataPartBase::GetLocation");
			assert(m_ptrDataObject->GetMasterDataPart()&&"aDataPartBase::GetLocation");
			return m_ptrDataObject->GetMasterDataPart()->m_vLocation;
		}
		const _FOMATH::Rotator& aDataPartBase::GetRotation()
		{
			assert(m_ptrDataObject&&"aDataPartBase::GetLocation");
			assert(m_ptrDataObject->GetMasterDataPart()&&"aDataPartBase::GetLocation");
			return m_ptrDataObject->GetMasterDataPart()->m_rRotation;
		}

		void aDataPartBase::SetLocation(const _FOMATH::Vector& loc)
		{
			FoGGESetBit(m_uiDataModificationFlag,eCP_Location);
		    m_vLocation=loc;		
		}
		void aDataPartBase::SetRotation(const _FOMATH::Rotator& rot)
		{
			FoGGESetBit(m_uiDataModificationFlag,eCP_Rotation);
			m_rRotation=rot;
		}
		//@}
	}
}